package de.traveltainment.concept.envers.database;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Default;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Created by borlis on 13.06.2014.
 */
@ApplicationScoped
public class EntityManagerProvider {

    private static final String DYNAMIX_CONFIG_SERVICE = "DCS_PU";

    private final Map<String, String> properties = new HashMap<String, String>();

    @Inject
    private Logger logger;

    @PersistenceContext(unitName = DYNAMIX_CONFIG_SERVICE)
    private EntityManagerFactory emFactory;

    @PostConstruct
    private void init(){
        try {
//            properties.put("javax.persistence.sharedCache.mode", "ENABLE_SELECTIVE");
//            properties.put("hibernate.cache.provider_class", "net.sf.ehcache.hibernate.EhCacheProvider");
//            properties.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory");

            // get the property value and put them to jpa properties
            properties.put("hibernate.connection.driver_class", JdbcPropertiesReader.getJdbcProperties().getProperties().getProperty("driver"));
            properties.put("hibernate.connection.url",JdbcPropertiesReader.getJdbcProperties().getProperties().getProperty("url"));
            properties.put("hibernate.connection.username",JdbcPropertiesReader.getJdbcProperties().getProperties().getProperty("username"));
            properties.put("hibernate.connection.password",JdbcPropertiesReader.getJdbcProperties().getProperties().getProperty("password"));

            // -=-=-=-=-=-=-
            logger.log(Level.ALL, "----------------------------------------");
            logger.log(Level.ALL, "** Current system properties **");
            for (Object property : System.getProperties().keySet()) {
                logger.log(Level.ALL, property + "=" + System.getProperties().get(property));
            }
            logger.log(Level.ALL, "----------------------------------------");

            if (emFactory == null) {
                emFactory = Persistence.createEntityManagerFactory(DYNAMIX_CONFIG_SERVICE, properties);
                logger.info("");
            }

            logger.info("----------------------------------------");
            logger.info("* Entity Manager Factory init **");
            logger.info("* DB connection = " + emFactory.getProperties().get("hibernate.connection.url"));
            logger.info("* Cache = " + emFactory.getCache().toString());
            logger.info("----------------------------------------");

        } catch (Throwable t) {
            logger.log(Level.SEVERE, "Failed to init EntityManagerFactory.", t);
        }
    }

    @Produces
    @RequestScoped
    @Default
    public EntityManager produceEntityManager() {
        try {
            EntityManager em = emFactory.createEntityManager(properties);
            logger.log(Level.FINE, "-> Entity Manager hashCode = " + em.hashCode());
            return em;
        } catch (Throwable t) {
            logger.log(Level.SEVERE, "Failed to get current session object.", t);
            throw new ExceptionInInitializerError(t);
        }
    }

    @PreDestroy
    private void destroy() {
        if (emFactory.isOpen()) {
            emFactory.close();
        }
    }

}
